#ifndef MATHHANDLER_H
#define MATHHANDLER_H

#include "systemCallHandler.h"
#include <QtMath>
#include <QRandomGenerator>
#include <QMap>

/**
 * @brief 三角函数类型枚举
 */
enum class TrigFunction {
    Sine = 1,        // 正弦
    Cosine = 2,      // 余弦
    Tangent = 3,     // 正切
    ArcSine = 4,     // 反正弦
    ArcCosine = 5,   // 反余弦
    ArcTangent = 6   // 反正切
};

/**
 * @brief 数学运算处理器类
 * 
 * 处理所有数学运算相关的系统调用，包括三角函数、对数、指数、
 * 随机数生成、数论函数等高级数学运算。
 * 支持的中断号范围：0x40-0x4F
 */
class MathHandler : public SystemCallHandler
{
    Q_OBJECT

public:
    explicit MathHandler(QObject *parent = nullptr);
    ~MathHandler() override;

    // 重写基类虚函数
    SystemCallResult handleInterrupt(int interruptNumber, CpuSimulator* cpu) override;
    QPair<int, int> getSupportedInterruptRange() const override;
    QString getDescription() const override;
    void reset() override;

private:
    /**
     * @brief INT 0x40 - 基础算术运算
     * 参数：AX=操作数1, BX=操作数2, CX=运算类型
     * 返回：DX=运算结果
     */
    SystemCallResult handleBasicArithmetic(CpuSimulator* cpu);

    /**
     * @brief INT 0x41 - 高级数学运算
     * 参数：AX=运算类型, BX=操作数
     * 返回：CX=运算结果
     */
    SystemCallResult handleAdvancedMath(CpuSimulator* cpu);

    /**
     * @brief INT 0x42 - 三角函数计算
     * 参数：AX=函数类型, BX=角度值（度数*100）
     * 返回：CX=函数值（定点数）
     */
    SystemCallResult handleTrigonometricFunction(CpuSimulator* cpu);

    /**
     * @brief INT 0x43 - 对数函数运算
     * 参数：AX=真数, BX=底数（0表示自然对数）
     * 返回：CX=结果（定点数，放大1000倍）
     */
    SystemCallResult handleLogarithmFunction(CpuSimulator* cpu);

    /**
     * @brief INT 0x44 - 指数函数运算
     * 参数：AX=底数, BX=指数
     * 返回：CX=结果
     */
    SystemCallResult handleExponentialFunction(CpuSimulator* cpu);

    /**
     * @brief INT 0x45 - 平方根运算
     * 参数：AX=被开方数
     * 返回：BX=平方根（定点数，放大1000倍）
     */
    SystemCallResult handleSquareRoot(CpuSimulator* cpu);

    /**
     * @brief INT 0x46 - 随机数生成
     * 参数：AX=最小值, BX=最大值
     * 返回：CX=随机数
     */
    SystemCallResult handleRandomGeneration(CpuSimulator* cpu);

    /**
     * @brief INT 0x47 - 最大公约数计算
     * 参数：AX=数值1, BX=数值2
     * 返回：CX=最大公约数
     */
    SystemCallResult handleGreatestCommonDivisor(CpuSimulator* cpu);

    /**
     * @brief INT 0x48 - 最小公倍数计算
     * 参数：AX=数值1, BX=数值2
     * 返回：CX=最小公倍数
     */
    SystemCallResult handleLeastCommonMultiple(CpuSimulator* cpu);

    /**
     * @brief INT 0x49 - 质数判断
     * 参数：AX=待判断数值
     * 返回：BX=结果（1=质数, 0=非质数）
     */
    SystemCallResult handlePrimeCheck(CpuSimulator* cpu);

    /**
     * @brief INT 0x4A - 阶乘计算
     * 参数：AX=数值
     * 返回：BX=阶乘结果（低位）, CX=阶乘结果（高位）
     */
    SystemCallResult handleFactorial(CpuSimulator* cpu);

    /**
     * @brief INT 0x4B - 组合数计算
     * 参数：AX=n, BX=r（C(n,r)）
     * 返回：CX=组合数结果
     */
    SystemCallResult handleCombination(CpuSimulator* cpu);

    /**
     * @brief INT 0x4C - 排列数计算
     * 参数：AX=n, BX=r（P(n,r)）
     * 返回：CX=排列数结果
     */
    SystemCallResult handlePermutation(CpuSimulator* cpu);

    /**
     * @brief INT 0x4D - 绝对值计算
     * 参数：AX=数值
     * 返回：BX=绝对值
     */
    SystemCallResult handleAbsoluteValue(CpuSimulator* cpu);

    /**
     * @brief INT 0x4E - 求最大值
     * 参数：AX=数组地址, BX=数组长度
     * 返回：CX=最大值, DX=最大值索引
     */
    SystemCallResult handleFindMaximum(CpuSimulator* cpu);

    /**
     * @brief INT 0x4F - 求最小值
     * 参数：AX=数组地址, BX=数组长度
     * 返回：CX=最小值, DX=最小值索引
     */
    SystemCallResult handleFindMinimum(CpuSimulator* cpu);

    // 辅助数学函数

    /**
     * @brief 计算最大公约数（欧几里得算法）
     * @param a 数值1
     * @param b 数值2
     * @return int 最大公约数
     */
    int calculateGcd(int a, int b);

    /**
     * @brief 计算最小公倍数
     * @param a 数值1
     * @param b 数值2
     * @return int 最小公倍数
     */
    int calculateLcm(int a, int b);

    /**
     * @brief 判断是否为质数
     * @param n 待判断数值
     * @return bool 是否为质数
     */
    bool isPrime(int n);

    /**
     * @brief 计算阶乘
     * @param n 数值
     * @return qint64 阶乘结果
     */
    qint64 calculateFactorial(int n);

    /**
     * @brief 计算组合数 C(n,r)
     * @param n 总数
     * @param r 选择数
     * @return qint64 组合数结果
     */
    qint64 calculateCombination(int n, int r);

    /**
     * @brief 计算排列数 P(n,r)
     * @param n 总数
     * @param r 选择数
     * @return qint64 排列数结果
     */
    qint64 calculatePermutation(int n, int r);

    /**
     * @brief 计算三角函数
     * @param funcType 函数类型
     * @param angle 角度（度数）
     * @return double 计算结果
     */
    double calculateTrigFunction(TrigFunction funcType, double angle);

    /**
     * @brief 将角度转换为弧度
     * @param degrees 角度
     * @return double 弧度
     */
    double degreesToRadians(double degrees);

    /**
     * @brief 将弧度转换为角度
     * @param radians 弧度
     * @return double 角度
     */
    double radiansToDegrees(double radians);

    /**
     * @brief 将浮点数转换为定点数（放大1000倍）
     * @param value 浮点数
     * @return int 定点数
     */
    int doubleToFixedPoint(double value);

    /**
     * @brief 将定点数转换为浮点数（缩小1000倍）
     * @param fixedPoint 定点数
     * @return double 浮点数
     */
    double fixedPointToDouble(int fixedPoint);

    /**
     * @brief 从内存读取整数数组
     * @param cpu CPU模拟器指针
     * @param address 数组起始地址
     * @param length 数组长度
     * @return QList<int> 整数数组
     */
    QList<int> readIntArrayFromMemory(CpuSimulator* cpu, int address, int length);

    /**
     * @brief 验证数学运算参数
     * @param operation 运算类型
     * @param params 参数列表
     * @return bool 参数是否有效
     */
    bool validateMathParameters(const QString& operation, const QList<int>& params);

private:
    QRandomGenerator* randomGenerator;          // 随机数生成器
    QMap<QString, double> constantsTable;       // 数学常数表
    
    // 数学常数
    static constexpr double PI = 3.14159265358979323846;
    static constexpr double E = 2.71828182845904523536;
    static constexpr int FIXED_POINT_SCALE = 1000;     // 定点数缩放因子
    static constexpr int MAX_FACTORIAL = 20;           // 最大阶乘计算数
    static constexpr int MAX_ARRAY_SIZE = 1024;        // 最大数组大小
};

#endif // MATHHANDLER_H 